﻿#include "FITKAcousticsVTKCommons.h"

// Qt
#include <QApplication>

// APP
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKAppFramework/FITKRunTimeSetting.h"

// Data
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscNodeList.h"

namespace Exchange
{
    // Initialize color list.
    //@{
    QList<QColor> FITKAcousticsVTKCommons::s_colorList =
    {
        QColor(69, 139, 116), QColor(245, 245, 220), QColor(187, 58, 58),
        QColor(0, 94, 157), QColor(193, 205, 205), QColor(222, 184, 135),
        QColor(177, 198, 237), QColor(139, 136, 120), QColor(233, 150, 122),
        QColor(189, 183, 107), QColor(139, 10, 80), QColor(49, 58, 151),
        QColor(202, 217, 187), QColor(238, 201, 0), QColor(173, 216, 230),
        QColor(110, 123, 139), QColor(139, 71, 137), QColor(238, 232, 170),
        QColor(184, 206, 198), QColor(184, 184, 219), QColor(206, 164, 107),
        QColor(106, 90, 205), QColor(238, 233, 233), QColor(0, 51, 102)
    };
    //@}

    // Initialize colors.
    //@{
    QColor FITKAcousticsVTKCommons::s_geoVertexColor = Qt::green;
    QColor FITKAcousticsVTKCommons::s_geoEdgeColor = Qt::black;
    QColor FITKAcousticsVTKCommons::s_geoFaceColor = QColor(255, 255, 50);
    QColor FITKAcousticsVTKCommons::s_geoSolidColor = QColor(0, 200, 255);
    QColor FITKAcousticsVTKCommons::s_meshFaceColor = Qt::gray; // Default and un-assigned color.
    QColor FITKAcousticsVTKCommons::s_meshFaceHighlightColor = Qt::yellow;
    QColor FITKAcousticsVTKCommons::s_SEANodesColor = QColor(35, 100, 150);
    QColor FITKAcousticsVTKCommons::s_SEAFreeEdgesColor = QColor(255, 0, 255);
    QColor FITKAcousticsVTKCommons::s_SEASubSysBeamColor = Qt::black;
    QColor FITKAcousticsVTKCommons::s_SEASubSysShellColor = QColor(120, 255, 0);
    QColor FITKAcousticsVTKCommons::s_SEASubSysCavityColor = QColor(210, 210, 210);
    QColor FITKAcousticsVTKCommons::s_SEASubSysSemiInfFluidColor = QColor(0, 130, 255);
    QColor FITKAcousticsVTKCommons::s_SEAJunctionEnabledColor = Qt::red;
    QColor FITKAcousticsVTKCommons::s_SEAJunctionDisabledColor = Qt::white;
    QColor FITKAcousticsVTKCommons::s_FEJunctionEnabledColor = Qt::blue;
    QColor FITKAcousticsVTKCommons::s_FEJunctionPoint2EnabledColor = QColor(140, 140, 70);
    QColor FITKAcousticsVTKCommons::s_FEJunctionDisabledColor = Qt::white;
    QColor FITKAcousticsVTKCommons::s_FEFaceColor = QColor(0, 255, 255);
    QColor FITKAcousticsVTKCommons::s_postNullColor = Qt::black;
    QColor FITKAcousticsVTKCommons::s_postAboveColor = Qt::white;
    QColor FITKAcousticsVTKCommons::s_postBelowColor = Qt::black;
    //@}
    
    // Initialize size.
    //@{
    double FITKAcousticsVTKCommons::s_highlightPointSize = 10.;
    double FITKAcousticsVTKCommons::s_highlightLineWidth = 3.;
    QPair<int, int> FITKAcousticsVTKCommons::s_pictureSize = QPair<int, int>(70, 70);
    double FITKAcousticsVTKCommons::s_flatShellScaleFactor = 0.7;
    double FITKAcousticsVTKCommons::s_curShellScaleFactor = 0.85;
    double FITKAcousticsVTKCommons::s_cavityScaleFactor = 0.7;
    //@}

    // Initialize properties.
    //@{
    double FITKAcousticsVTKCommons::s_defaultTransparency = 0.3;
    double FITKAcousticsVTKCommons::s_defaultModelTransparency = 0.7;
    double FITKAcousticsVTKCommons::s_defaultNullPostTransparency = 0.7;
    //@}
    
    // Advanced.
    double FITKAcousticsVTKCommons::s_polygonOffsetCAD = 2.;
    double FITKAcousticsVTKCommons::s_polygonOffsetSEABeam = 0;
    double FITKAcousticsVTKCommons::s_polygonOffsetSEAShell = 0;
    double FITKAcousticsVTKCommons::s_polygonOffsetSEACavity = 1;
    double FITKAcousticsVTKCommons::s_polygonOffsetSEAJunction = -1;
    double FITKAcousticsVTKCommons::s_polygonOffsetFEStruct = -3;
    double FITKAcousticsVTKCommons::s_polygonOffsetFECavity = -3;
    double FITKAcousticsVTKCommons::s_polygonOffsetFEFace = -4;
    double FITKAcousticsVTKCommons::s_polygonOffsetTopMarks = -5;
    //@}

    QString FITKAcousticsVTKCommons::GetTempFolder()
    {
        return qApp->applicationDirPath() + "/temp/3d/";
    }

    QColor FITKAcousticsVTKCommons::GetColorByIndex(int index)
    {
        // Default color list.
        return s_colorList[index % s_colorList.count()];
    }

    QColor FITKAcousticsVTKCommons::GetRandomColor()
    {
        //int index = rand() % s_colorList.count();
        //return s_colorList[index];

        int r = rand() % 255;
        int g = rand() % 255;
        int b = rand() % 255;
        return QColor(r, g, b);
    }

    void FITKAcousticsVTKCommons::QColorToDouble3(QColor color, double* rgbf)
    {
        rgbf[0] = color.redF();
        rgbf[1] = color.greenF();
        rgbf[2] = color.blueF();
    }

    void FITKAcousticsVTKCommons::QColorToInt3(QColor color, int* rgb)
    {
        rgb[0] = color.red();
        rgb[1] = color.green();
        rgb[2] = color.blue();
    }

    double FITKAcousticsVTKCommons::GetRandomPolygonOffset(int minRange, int maxRange, int prec)
    {
        // Deal with the precision.
        if (prec < 2)
        {
            prec = 6;
        }

        // Enlarge the range.
        double scale = pow(10., prec);
        int min = qMin(minRange, maxRange) * scale + 1;
        int max = qMax(minRange, maxRange) * scale - 1;

        double iVal = rand() % (max - min) + min;
        return iVal / scale;
    }

    bool FITKAcousticsVTKCommons::GetSEANodePositionById(Acoustics::FITKAcousticsDiscNodeList* seaNodes, int nodeId, double* pos)
    {
        if (!seaNodes)
        {
            return false;
        }

        // Get the SEA node by node id.
        Core::FITKNode* sNode = seaNodes->getNodeByID(nodeId);
        if (!sNode)
        {
            return false;
        }

        sNode->getCoor(pos);
        return true;
    }

    bool FITKAcousticsVTKCommons::GetSEANodePositionByIndex(Acoustics::FITKAcousticsDiscNodeList* seaNodes, int nodeIndex, double* pos)
    {
        if (!seaNodes)
        {
            return false;
        }

        // Get the SEA node by node index.
        Core::FITKNode* sNode = seaNodes->getNodeAt(nodeIndex);
        if (!sNode)
        {
            return false;
        }

        sNode->getCoor(pos);
        return true;
    }

    void FITKAcousticsVTKCommons::ClearVisibilityRuntimeSettings()
    {
        AppFrame::FITKRunTimeSetting* rtSettings = FITKAPP->getGlobalData()->getRunTimeSetting();
        if (!rtSettings)
        {
            return;
        }

        // Main
        rtSettings->removeVarient(RTS_KEY_VISIBLE_CAD);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_GEOMETRY);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_MESH);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_GRAPH_NODES);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_UNUSED_NODES);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SUB_SYSTEMS);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_FREE_EDGES);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_JUNCTIONS);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_JUNCTION_POINTS);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_JUNCTION_LINES);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_JUNCTION_AREAS);

        // Geometry
        rtSettings->removeVarient(RTS_KEY_VISIBLE_GEOM_VERTS);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_GEOM_EDGES);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_GEOM_FACES);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_GEOM_SOLIDS);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_GEOM_VECTOR);

        // SEA
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_SUBSYS);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_SUBSYS_BEAM);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_SUBSYS_FLAT_PLATE);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_SUBSYS_S_CUR_PLATE);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_SUBSYS_D_CUR_PLATE);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_SUBSYS_CYLINDER_PLATE);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_SUBSYS_CAVITY);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_SUBSYS_SEMI_INF_FLUID);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_JUNC_POINTS);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_JUNC_LINES);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_SEA_JUNC_AREAS);
        rtSettings->removeVarient(RTS_KEY_SCALE_MODE);

        // FE
        rtSettings->removeVarient(RTS_KEY_VISIBLE_FE_SURFACE);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_FE_STRUCT);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_FE_ACOUSTICS);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_FE_JUNC_POINTS);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_FE_JUNC_LINES);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_FE_JUNC_AREAS);

        // Mix
        rtSettings->removeVarient(RTS_KEY_VISIBLE_MIX_JUNC_POINTS);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_MIX_JUNC_LINES);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_MIX_JUNC_AREAS);

        // Load
        rtSettings->removeVarient(RTS_KEY_VISIBLE_LOADS);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_LOAD_POINTFORCE);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_LOAD_POWER);
        rtSettings->removeVarient(RTS_KEY_VISIBLE_LOAD_CONSTRAINT);

        // Custom Size Ratio
        rtSettings->removeVarient(RTS_KEY_SIZE_RATIO_POINTS);
        rtSettings->removeVarient(RTS_KEY_SIZE_RATIO_LINES);
        rtSettings->removeVarient(RTS_KEY_SIZE_RATIO_SOURCES);
    }

    QColor FITKAcousticsVTKCommons::getLoadExcForMomColor(bool isEnable)
    {
        if (isEnable) {
            return QColor(116, 0, 116);
        }
        else {
            return QColor(219, 219, 219);
        }
    }

    QColor FITKAcousticsVTKCommons::getFESubSysStructureColor(bool isEnable)
    {
        if (isEnable) {
            return QColor(97, 193, 0);
        }
        else {
            return QColor(219, 219, 219);
        }
    }

    QColor FITKAcousticsVTKCommons::getFESubSysAcousticColor()
    {
        return QColor(154, 154, 154);
    }
}   // namespace Exchange